/**
 * 任务队列并发任务控制
 */

type PrTask = () => Promise<any>

interface QueueList {
  task: PrTask,
  resolve: (value: any) => void,
  reject: (reason: any) => void,
  priority: Priority
}

// 优先级
enum Priority {
  low = -1,
  normal = 0,
  high = 1
}

export default class TaskQueue {
  // 任务队列
  private _queueList: QueueList[] = []
  // 正在执行的任务数
  private _running: number = 0
  constructor(public parallel = 2) {
    this.parallel = parallel // 并发数
  }

  addTask(task: PrTask, priority: Priority = 0) {
    return new Promise((resolve, reject) => {
			this._queueList.push({
				task,
				resolve,
				reject,
        priority
			})
			this._runTask()
		})
  }

  private _runTask() {
    while (this._running < this.parallel && this._queueList.length) {
      // 根据优先级执行任务
      this._queueList.sort((a, b) => b.priority - a.priority)
			const { task, resolve, reject } = this._queueList.shift() as QueueList
			task()
				.then(resolve, reject)
				.finally(() => {
					this._running--
					this._runTask()
				})
			this._running++
		}
  }

  get isRunning() {
    return this._running > 0
  }
}